package org.stone.project.logInterface.aop;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.stone.project.common.pojo.annotation.LogMethod;
import org.stone.project.common.pojo.constant.AopExecOrder;
import org.stone.project.logInterface.pojo.po.MethodLog;
import org.stone.project.logInterface.service.UserInfoService;
import org.stone.project.logInterface.utils.LogUtil;

import java.lang.reflect.Method;

@Aspect
@Component
@Order(value = AopExecOrder.METHOD_LOG_ORDER)
@ConditionalOnProperty(name = "logging.aop.method.enabled",havingValue = "true", matchIfMissing = false)
public class MethodLogAop {
    @Autowired(required = false)
    private UserInfoService userInfoService;
    /**
     * 方法日志
     * @param joinPoint
     * @param logMethod
     * @return
     */
    @Around(value = "@annotation(logMethod)")
    public Object addMethodLog(ProceedingJoinPoint joinPoint, LogMethod logMethod){
        //获取参数
        Object[] args = joinPoint.getArgs();
        MethodLog requestLog = new MethodLog();
        requestLog.setMethod(JSONUtil.toJsonStr(args));
        if (logMethod.recordMethod()){
            MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
            Method method = methodSignature.getMethod();
            requestLog.setMethod(method.getDeclaringClass().getName()+"."+method.getName());
        }
        if (logMethod.recordParam() && ObjectUtil.isNotNull(args)){
            requestLog.setMethodParam(JSONUtil.toJsonStr(args));
        }
        if (logMethod.recordUsername() && ObjectUtil.isNotNull(userInfoService)){
            requestLog.setCreateUserName(userInfoService.getUserPrimaryInfo());
        }
        try {
            Object proceed = joinPoint.proceed(args);
            if (logMethod.recordReturn() && ObjectUtil.isNotNull(proceed)){
                requestLog.setMethodReturn(JSONUtil.toJsonStr(proceed));
            }
            return proceed;
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }finally {
            LogUtil.addMethodLog(requestLog);
        }
    }
}
